package Common

import (
	"fmt"
	"github.com/spf13/viper"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
	"net/url"
)

var DB *gorm.DB //声明全局变量数据库DB 之后可以使用DB调用数据库

func InitDB() *gorm.DB {
	//从config.yml读取数据库配置并建立连接 gorm自动管理一个连接池
	args := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=%s",
		//数据库用户名
		viper.GetString("datasource.username"),
		//数据库密码
		viper.GetString("datasource.password"),
		//数据库主机
		viper.GetString("datasource.host"),
		//数据库端口
		viper.GetString("datasource.port"),
		//数据库名称
		viper.GetString("datasource.database"),
		//数据库字符集(一般都是utf8mb4)
		viper.GetString("datasource.charset"),
		//数据库时区
		url.QueryEscape(viper.GetString("datasource.loc")))
	//建立连接并赋值
	db, errGorm := gorm.Open(mysql.Open(args), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			//设置表前缀
			TablePrefix: viper.GetString("datasource.prefix"),
			//表名是否是单数(默认false,表名会加s)
			SingularTable: true,
		},
	})
	//捕捉数据库连接错误
	if errGorm != nil {
		panic("连接数据库失败:" + errGorm.Error())
	}
	//检查表的结构 表不存在会自动新建 表的结构在文件夹下database.go中 不需要新建或者检查的需要注释掉
	_ = db.AutoMigrate(&Admin{})          //表名lvbu_admin
	_ = db.AutoMigrate(&App{})            //表名lvbu_app
	_ = db.AutoMigrate(&GoodsInfo{})      //表名lvbu_goods_info
	_ = db.AutoMigrate(&GoodsType{})      //表名lvbu_goods_type
	_ = db.AutoMigrate(&Logger{})         //表名lvbu_logger
	_ = db.AutoMigrate(&GoodsInventory{}) //表名lvbu_goods_inventory
	//赋值全局变量
	DB = db
	return db
}

func GetDB() *gorm.DB {
	//返回全局变量数据库DB
	return DB
}

// App 数据表结构（应用表）
type App struct {
	gorm.Model
	AppName string `gorm:"type:varchar(32);unique;not null"` // 应用名称
	Msg     string `gorm:"type:varchar(32);"`                // 备注
}

// Admin 数据表结构（用户账号表）
type Admin struct {
	gorm.Model
	Account  string `gorm:"type:varchar(11);not null"` // 账户
	Password string `gorm:"type:varchar(32);not null"` // 密码
	App      int32  `gorm:"type:int(10);not null"`     // 用户所属应用id
	Role     int32  `gorm:"type:int(10);not null"`     // 用户所属角色id
	Msg      string `gorm:"type:varchar(32);"`         // 备注
}

// GoodsInfo 数据表结构（商品信息表）
type GoodsInfo struct {
	gorm.Model
	GoodsName string  `gorm:"type:varchar(32);not null"`        // 商品名称
	txm       string  `gorm:"type:varchar(32);unique;not null"` // 商品条形码
	price     float64 `gorm:"type:decimal(9,2);not null"`       // 商品价格
	typeId    int32   `gorm:"type:int(10);not null"`            // 商品类别id
	status    int32   `gorm:"type:int(10);not null"`            // 商品状态
	app       int32   `gorm:"type:int(10);not null"`            // 表所属应用
	Msg       string  `gorm:"type:varchar(32);"`                // 备注
}

// GoodsType 数据表结构（商品类别表）
type GoodsType struct {
	gorm.Model
	TypeName string `gorm:"type:varchar(32);not null"` // 类别名称
	Parent   string `gorm:"type:varchar(32);not null"` // 上级类别
	app      int32  `gorm:"type:int(10);not null"`     // 表所属应用
	Msg      string `gorm:"type:varchar(32);"`         // 备注
}

// Logger 数据表结构（日志表）
type Logger struct {
	gorm.Model
	Log     string `gorm:"type:varchar(32);not null"` // 日志内容
	LogType int32  `gorm:"type:int(10);not null"`     // 日志类型
	app     int32  `gorm:"type:int(10);not null"`     // 表所属应用
}

// GoodsInventory 数据表结构（商品库存变动表）
type GoodsInventory struct {
	gorm.Model
	GoodsId       int32  `gorm:"type:int(10);not null"` // 商品ID
	InventoryType int32  `gorm:"type:int(10);not null"` // 库存变动类型
	amount        int32  `gorm:"type:int(10);not null"` // 库存变动数量
	typeId        int32  `gorm:"type:int(10);not null"` // 商品类别id
	app           int32  `gorm:"type:int(10);not null"` // 表所属应用
	Msg           string `gorm:"type:varchar(32);"`     // 备注
}

// Login Json结构体
type Login struct {
	Username  string `json:"username"`
	Password  string `json:"password"`
	Timestamp int64  `json:"timestamp"`
}
